package ar.com.photo_admin.service

import javax.annotation.PostConstruct

import org.springframework.web.multipart.*

import ar.com.photo_admin.domain.Event
import ar.com.photo_admin.domain.EventAlbum
import ar.com.photo_admin.domain.EventPhoto
import ar.com.photo_admin.domain.User
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest
import grails.converters.*

import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes

/**
 * Service for domain class Event
 */
class EventService extends BaseService {

	def eventPhotoService
	
	/**
	 * Confirms the changes made on the event. 
	 */
	def confirmChangesEvent(Event event){
		
		addNewPhotos(event)
		deleteMarkedPhotos(event)		
		event.published = false
			
		event.save(flush:true)		
	}
	
	/**
	 * Discards any changes made to the event.
	 */
	def cancelChangesEvent(Event event) {
		
		deleteTemporalPhotos(event.number)
		cancelDeletePhotos(event)
		
		event.save(flush:true)
	}
	
	/**
	 * Cancel the creation of a new event (Deletes the photos). 
	 */
	def cancelNewEvent(eventNumber) {
		deleteTemporalPhotos(eventNumber)
	}
	
	/**
	 * Deletes the photos that were going to be added to the event after confirmation.
	 */
	def deleteTemporalPhotos(eventNumber) {
		def photos = EventPhoto.findAllByTemporalEventNumber(eventNumber)
		deletePhotosCollection(photos)
	}

	/**
	 * Deletes the marked to delete photos.
	 */
	def deleteMarkedPhotos(event) {
		def photos = EventPhoto.findAllByToBeDeletedAndEvent(true, event)		
		deletePhotosCollection(photos)
	}	
	
	def deletePhotosCollection(photos) {
		User user = springSecurityService.getCurrentUser()
		
		photos.each() { EventPhoto photo ->
			
			if (user.isOwner(photo)) {

				Event photoEvent = photo.event
				
				if (photoEvent != null) {
					
					// Checks if it is cover photo of the event
					EventPhoto cover = photoEvent.coverPhoto
					if (photo.id == cover?.id) {
						photoEvent.coverPhoto = null
					}
					
					// Checks if it should be deleted from any album
					photo.getAlbums().each() { album ->
						photo.removeFromAlbums(album)
					}
					
					// Checks if it is cover photo of any album of the event
					def coverOfAlbums = EventAlbum.findAllByCoverPhoto(photo)
					coverOfAlbums.each {
						it.coverPhoto = null
					}
					
					photo.deleted = true
					photo.save(flush:true)
				} else {
					photo.delete(flush:true)
				}				
			}
		}
	}
	
	/**
	 * Reverts the photos that were marked to be delete.
	 */
	def cancelDeletePhotos(Event event) {
		def photos = EventPhoto.findAllByToBeDeletedAndEvent(true, event)
		
		photos.each(){
			it.toBeDeleted = false
		}
	}
		
	/**
	 * Associates the photos to the event using the event number stored in the photo.
	 */
	def addNewPhotos(Event event) {
		def photos = EventPhoto.findAllByTemporalEventNumber(event.number)
				
		photos.each(){
			it.temporalEventNumber = 0
			event.addToPhotos(it)
		}
	}
	
	/**
	 * Gets event photos that were not deleted.
	 */
	def getEventPhotos(Event event) {
		return event?.photos.findAll{ !it.deleted }
	}

	/**
	 * Gets confirmed and not confirmed event photos in JSON format.
	 */
	def getEventConfirmedAndNotConfirmedPhotosAsJSON(Event event) {
		def photos = []
		
		if (event.id)
			photos.addAll(getEventPhotos(eventId))
		
		photos.addAll(EventPhoto.findAllByTemporalEventNumber(event.number))		
		
		return convertPhotosToJSON(photos)
	}	

	/**
	 * Gets the event photos in JSON format.
	 */
	def getEventPhotosAsJSON(Event event){
		def photos = getEventPhotos(event)
		return convertPhotosToJSON(photos)
	}
	
	/**
	 * Converts an array of photos into JSON.
	 */
	def convertPhotosToJSON(photos){
		return eventPhotoService.convertPhotosToJSON(photos)
	}

	/**
	 * Deletes an event photo temporally (mark as to be deleted) if the photo 
	 * was uploaded by the logged in user or if the user is an owner if the event.  
	 */
	def deletePhotoTemporally(photoId) {		
		EventPhoto photo = eventPhotoService.getAndCheckOwnership(photoId)
		
		if (photo) {
			photo.toBeDeleted = true
			photo.save(flush:true)
		} 
	}

	/**
	 * Creates an album with all the photos of the event.
	 */
	def addAlbumWithAllPhotos(Event event) {
		
		def name = event.name
		def description = event.description
		def coverPhoto  = event.coverPhoto
		
		EventAlbum album = new EventAlbum(name: name, description: description, coverPhoto: coverPhoto)		
		
		event.addToAlbums(album)
		album.save(flush:true)
		
		event.photos.each { EventPhoto photo ->
			if (!photo.deleted)
				album.addToAlbumPhotos(photo)
		}
		
		album.save(flush:true)
	}
	
	/**
	 * Computes the next number in the sequence of events.
	 */
	def getNextEventNumber() {
		Event event = Event.find("FROM Event ORDER BY number desc")
		event != null ? event.number + 1 : 1
	}
}